import { memo, MouseEventHandler, useMemo, useState } from 'react';
import type { FC, PropsWithChildren } from 'react';
import { Link, useNavigate, useSearchParams } from 'react-router-dom';
import { Button, CheckboxOptionType, Empty, Radio, Spin, Tag } from 'antd';
import { resCategoryList } from '@/services/category';
import { resGoods } from '@/services/goods';
import { useInfiniteScroll, useRequest } from 'ahooks';
import NoMore from '@/components/NoMore';
import { renderCategoryItem } from '@/pages/Home/components/HomeCategory';
import HomeSearch from '@/pages/Home/components/HomeSearch';
import HomeTop from '@/pages/Home/components/HomeTop';
import { useGoDetail } from '@/hooks/useGoDetail';
import { createHtml, formatUrl } from '@/utils/format';

const SearchGoodsItem: FC<
  PropsWithChildren<{ data: API.QueryGoods; onClick: MouseEventHandler }>
> = ({ data, onClick }) => {
  return (
    <div
      className={
        'flex bg-blue-50 rounded-lg overflow-hidden cursor-pointer hover:ring-1 hover:ring-offset-4 transition hover:shadow-lg '
      }
      onClick={onClick}
    >
      <div>
        <img className={'w-24 h-32'} src={formatUrl(data.cover)} alt="" />{' '}
        <div className={'space-x-2 py-2 '}>
          <strong className={'text-red-600 text-lg'}>
            <em className={'text-xs px-0.5'}>￥</em>
            {data.price * data.discount}
          </strong>
          {data.discount < 1 ? (
            <i className={'line-through text-gray-600'}>
              <em className={'text-xs px-0.5'}>￥</em>
              {data.price}
            </i>
          ) : null}
        </div>
      </div>
      <div className={'p-4 w-56 space-y-2.5'}>
        <div
          className={'text-lg truncate'}
          dangerouslySetInnerHTML={createHtml(data._formatted.title)}
        />
        <div
          className={'truncate-2 text-sm'}
          dangerouslySetInnerHTML={createHtml(data._formatted.description)}
        />
        <div
          className={'truncate-2 text-sm'}
          dangerouslySetInnerHTML={createHtml(data._formatted.details)}
        />
        <Link to={`/user_page/` + data.user_id} className={'truncate-2'}>
          {data.user.name}
        </Link>
      </div>
    </div>
  );
};

const SearchGoodsItemMemo = memo(SearchGoodsItem);

const CategorySelect: FC<PropsWithChildren<{}>> = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const category_id = searchParams.get('category_id') || 0;
  const [selectedTag, setSelectedTag] = useState<number>(Number(category_id));
  const { data } = useRequest(resCategoryList);
  const tagsData = useMemo(() => {
    return data && renderCategoryItem(data);
  }, [data]);

  const handleChange = (tag: API.CategoryListStruct, checked: boolean) => {
    let id = checked ? tag.id : 0;
    setSelectedTag(id);
    id
      ? searchParams.set('category_id', String(id))
      : searchParams.delete('category_id');
    setSearchParams(searchParams);
  };

  return (
    <div className={'text-center mt-6'}>
      <span className={'text-black text-base font-bold mr-4'}>分类:</span>
      {tagsData?.map((tag) => (
        <Tag.CheckableTag
          key={tag.id}
          checked={selectedTag === tag.id}
          onChange={(checked) => handleChange(tag, checked)}
        >
          {tag.name}
        </Tag.CheckableTag>
      ))}
    </div>
  );
};

type FilterCondition = { is_recommend: number; is_on?: number };
type SortCondition = { price: string; sales: string };

const isRecommendOptions: CheckboxOptionType[] = [
  {
    label: '已被推荐',
    value: 1,
  },
  {
    label: '未被推荐',
    value: 0,
  },
];
const priceSort: CheckboxOptionType[] = [
  {
    label: '按价格由高到低',
    value: 'price:desc',
  },
  {
    label: '按价格由低到高',
    value: 'price:asc',
  },
];
const salesSort: CheckboxOptionType[] = [
  {
    label: '按销量由高到低',
    value: 'sales:desc',
  },
  {
    label: '按销量由低到高',
    value: 'sales:asc',
  },
];

const SearchPage: FC<PropsWithChildren<{}>> = () => {
  const [searchParams] = useSearchParams();
  const { goDetail } = useGoDetail();
  const [filterCondition, setFilterCondition] = useState<FilterCondition>(
    {} as FilterCondition
  );
  const [sortCondition, setSortCondition] = useState<SortCondition>(
    {} as SortCondition
  );

  const { data, loading, loadMore, loadingMore, noMore } =
    useInfiniteScroll<API.GoodsInfiniteData>(
      (currentData) => {
        return resGoods({
          limit: 18,
          offset: currentData ? currentData.offset + currentData.limit : 0,
          attributesToHighlight: ['*'],
          filter: [
            filterCondition.is_recommend > -1
              ? `is_recommend = ${filterCondition.is_recommend} `
              : '',
            filterCondition.is_on ? `is_on = ${filterCondition.is_on} ` : '',
            searchParams.has('category_id')
              ? `category_id = ${searchParams.get('category_id')}`
              : '',
          ],
          attributesToCrop: ['title', 'description', 'details'],
          sort: Object.values(sortCondition).filter((value) => value),
          cropLength: 10,
          q: searchParams.get('q') || '',
          highlightPreTag: "<strong class='text-blue-500' >",
          highlightPostTag: '</strong>',
        }).then((value) => {
          let result: API.GoodsInfiniteData;
          let { hits, ...rest } = value;
          result = { ...rest, list: value.hits };
          return result;
        });
      },
      {
        reloadDeps: [searchParams, filterCondition, sortCondition],
        target: document,
        isNoMore: (d) => {
          return (
            d?.list.length === 0 || !d || d?.list.length < d.offset + d.limit
          );
        },
      }
    );

  const searchForm = (
    <div className={'py-4 pl-4 space-x-4'}>
      <span className={'pr-4'}>筛选条件:</span>
      <Radio.Group
        options={isRecommendOptions}
        optionType="button"
        buttonStyle="solid"
        value={filterCondition.is_recommend}
        onChange={(e) => {
          setFilterCondition((preState) => {
            return { ...preState, is_recommend: Number(e.target.value) };
          });
        }}
      />
      <Radio.Group
        options={priceSort}
        optionType="button"
        buttonStyle="solid"
        value={sortCondition.price}
        onChange={(e) => {
          setSortCondition((preState) => {
            return { ...preState, price: e.target.value };
          });
        }}
      />
      <Radio.Group
        options={salesSort}
        optionType="button"
        buttonStyle="solid"
        value={sortCondition.sales}
        onChange={(e) => {
          setSortCondition((preState) => {
            return { ...preState, sales: e.target.value };
          });
        }}
      />
      <Button
        htmlType={'reset'}
        onClick={() => {
          setSortCondition({} as SortCondition);
          setFilterCondition({ is_recommend: -1 });
        }}
      >
        重置
      </Button>
    </div>
  );

  return (
    <div
      className={
        'min-h-screen w-[1200px] mx-auto bg-white p-6 my-4 rounded-lg relative' +
        ' shadow-[0_35px_60px_-15px_rgba(0,0,0,0.3)]'
      }
    >
      <HomeTop />
      <HomeSearch />
      <CategorySelect />
      <div className={'mt-10  bg-white font-serif rounded-lg'}>
        {searchForm}
        <div className={'py-8'}>
          <Spin spinning={loading}>
            <div
              className={
                'grid place-content-around grid-cols-3 place-items-center gap-y-10'
              }
            >
              {data && data.list.length > 0
                ? data.list
                    .filter((value) => value.stock > 0)
                    .map((value) => (
                      <SearchGoodsItemMemo
                        key={value.id}
                        data={value}
                        onClick={goDetail(value.id)}
                      />
                    ))
                : null}
            </div>
          </Spin>
          {data && data.list.length > 0 && (
            <div className={'w-[75%]  mt-10 mx-auto '}>
              <NoMore loadingMore={loadingMore} noMore={noMore} />
            </div>
          )}
          {!loading && data && data.list.length === 0 && <Empty />}
        </div>
      </div>
    </div>
  );
};

export default memo(SearchPage);
